package com.cyt.sys.extend.shiro;

import com.cyt.base.util.DictCode;
import com.cyt.base.util.StringUtils;
import com.cyt.sys.dao.SysMenuDao;
import com.cyt.sys.model.po.SysMenu;
import com.cyt.sys.model.po.SysUser;
import com.cyt.sys.model.vo.SysUserVo;
import com.cyt.sys.service.SysUserService;
import com.cyt.sys.service.SysParamConfigService;
import com.cyt.sys.util.SysContant;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: YuShengQiang
 * @Date: 2018-11-20 8:25
 * @Description:
 */

public class UserRealm extends AuthorizingRealm {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysMenuDao sysMenuDao;
    @Resource
    private SysParamConfigService sysParamConfigService;
    /**
     * 为当前登录的Subject授予角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()
        SysUser sysUser = (SysUser) super.getAvailablePrincipal(principals);
        List<String> roleList = new ArrayList<String>();
        List<String> permissionList = new ArrayList<String>();
        List<SysMenu> list= sysMenuDao.selectByEntity(new SysMenu(DictCode.MENU_TYPE_BTN, sysUser.getId()));
        for (SysMenu sysMenu :list){
            if(StringUtils.isNotEmpty(sysMenu.getPermission())){
                permissionList.add(sysMenu.getPermission());
            }
        }
        // 从数据库中获取当前登录用户的详细信息
        /*AdminForm form = new AdminForm();
        form.setUserName(username);
        Admin admin = adminService.getList(form).get(0);
        if (null != admin) {
            // 实体类User中包含有用户角色的实体类信息
            if (null != admin.getRoleId()) {
                // 获取当前登录用户的角色
                RoleForm roleForm = new RoleForm();
                roleForm.setId(admin.getRoleId());

                Role role = roleService.getList(roleForm).get(0);
                roleList.add(role.getName());

                // 实体类Role中包含有角色权限的实体类信息
                if (null != role.getPermissionsList()) {
                    String permissionsList[] = role.getPermissionsList().split(",");
                    // 获取权限
                    for (int i = 0; i < permissionsList.length; i++) {
                        PermissionsForm permissionsForm = new PermissionsForm();
                        permissionsForm.setId(Integer.parseInt(permissionsList[i]));

                        Permissions permi = permissionsService.getList(permissionsForm).get(0);
                        permissionList.add(permi.getCode());
                    }
                }
            }
        } else {
            throw new AuthorizationException();
        }*/
        // 为当前用户设置角色和权限
        SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
        /*roleList.add("admin");
        roleList.add("menu");
        simpleAuthorInfo.addRoles(roleList);
        permissionList.add("sys:menu:get");*/
        simpleAuthorInfo.addStringPermissions(permissionList);
        return simpleAuthorInfo;
    }

    /**
     * 验证当前登录的Subject
     *
     * 经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()时
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        // 获取基于用户名和密码的令牌
        AllUsernamePasswordToken token = (AllUsernamePasswordToken) authcToken;
        String salt=token.getSalt();
        String allPassword=token.getAllPassword();
        //获取用户信息
        List<SysUser> list= sysUserService.selectList(new SysUserVo(token.getUsername().toString()));
        if(list!=null && list.size()>0){
            SysUser sysUser =list.get(0);
            if(SysContant.USER_STATUS_NORMAL.equals(sysUser.getStatus())){
                AuthenticationInfo authenticationInfo =null;
                if(StringUtils.isEmpty(salt)){
                    authenticationInfo = new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes(sysUser.getSalt()), this.getName());
                }else{
                    authenticationInfo = new SimpleAuthenticationInfo(sysUser, allPassword, ByteSource.Util.bytes(salt), this.getName());
                }
                return authenticationInfo;
            }
            throw new DisabledAccountException();
        }else{
            throw new UnknownAccountException();
        }
    }

   /* public AuthorizationInfo checkLogin(){

    }*/
    /**
     * 将一些数据放到ShiroSession中,以便于其它地方使用
     *
     * 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到
     */
    private void setSession(Object key, Object value) {
        Subject currentUser = SecurityUtils.getSubject();
        if (null != currentUser) {
            Session session = currentUser.getSession();
            System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");
            if (null != session) {
                session.setAttribute(key, value);
            }
        }
    }
}
